<?php
/*
 * SimplePage class for ThinkPHP 2.0
 *
 * author: essoduke.org
 * modify: Mon, 17 January 2011 04:06:35 GMT
 */
class SimplePage extends Think
{
    // additional parameter
    public $parameter = null;
    // links count of pagination
    public $display = 10;
    // wrapper
    public $wrap = null;
    // compatible with original page class
    public $firstRow = 0;
    public $listRows = 0;

    // total rows
    protected $rows = 0;
    // rows per page to display
    protected $perpage = 10;
    // total pages
    protected $pages = 0;
    // current page
    protected $p = 1;
    // side offset
    protected $offset = 0;
    // first page
    protected $start = 1;
    // end page
    protected $end = 1;
    // configure
    protected $config = array(
        'records'     => 'Record:',
        'page'        => 'Page:',
        'prev'        => '&lt;',
        'next'        => '&gt;',
        'first'       => '|&lt;',
        'last'        => '&gt;|',
        'theme'       => '%wrapL% %records% %totalRow% %page% %nowPage%/%totalPage% %wrapR% %first% %prev% %linkPage% %next% %last%'
        /*
         * wrapL : wrapper left
         * wrapR : wrapper right
         * records: label for total records
         * totalRow: value of total rows
         * page : label for page
         * nowPage : current page
         * totalPage : total pages
         * first : 1st page link
         * last : last page link
         * linkPage: other pages link
         */
    );

    // Left, Right wrapper
    protected $wrap_L = null;
    protected $wrap_R = null;

    /*
     * SimplePage Construct
     *
     * @param: $rows / integer / total rows of record
     * @param: $perpage / integer / rows of per page
     * @param: $display / integer / pagination length
     * @param: $wrap / string / wrapper of pagination, eg: li
     * @param: $parameter / string / additional url querystring
     * @return: string
     */
    public function __construct ($rows, $perpage, $display = 10, $wrap = null, $parameter = null)
    {
        $this->rows       = intval($rows);
        $this->parameter  = $parameter;
        $this->display    = intval($display);
        $this->perpage    = intval($perpage);
        $this->pages      = ceil($this->rows / $this->perpage);
        $this->p          = (!empty($_GET[C('VAR_PAGE')]) && is_numeric($_GET[C('VAR_PAGE')]) ) ? intval($_GET[C('VAR_PAGE')]) : 1;
        $this->wrap       = $wrap;

        // make display to odd
        if (!$this->display & 1)
        {
            ++$this->dislpay;
        }

        // ensure current page is in range
        if (!empty($this->pages) && $this->p > $this->pages)
        {
            $this->p = $this->pages;
        }

        // wrapper
        if (null !== $this->wrap && !empty($this->wrap))
        {
            $this->wrap_L = "<$wrap>";
            $this->wrap_R = "</$wrap>";
        }

        // variables assign
        $this->offset = floor($this->display / 2);
        $this->start = 1;
        $this->end = $this->pages;
        $this->firstRow = ($this->p - 1) * $this->perpage;
        $this->listRows = $this->perpage;
    }

    /*
     * setting configure
     *
     * @param: $name / string / field's name
     * @param: $value / string / field's value
     */
    public function setConfig ($name, $value)
    {
        if (isset($this->config[$name]))
        {
            $this->config[$name] = $value;
        }
    }

    /*
     * return pagination html
     *
     * @return: string
     */
    public function show ()
    {
        if (0 === $this->rows)
        {
            return null;
        }

        // counting start and end position
        if ($this->pages > $this->display)
    		{
            if ($this->p > $this->offset)
            {
                $this->start = $this->p - $this->offset;
            }
            else
            {
                $this->end = $this->display;
            }

            if (($this->p + $this->offset) < $this->pages)
            {
                if ($this->p > $this->offset)
                {
                    $this->end = $this->p + $this->offset;
                }
            }
            else
            {
                $this->start = ($this->pages - $this->display) + 1;
            }
        }

        $p = C('VAR_PAGE');
        $host = $_SERVER['REQUEST_URI'];
        $url = $host . (strpos($host, '?') ? '&' : '?') . $this->parameter;

        // if the last / is existed then replace it to empty
        if (strlen($host) === strrpos($host, '/') + 1)
        {
            $host = substr($host, 0, -1);
        }

        // html code container
        $html = array();

        // parse url
        $parse = parse_url($url);
        if (isset($parse['query']))
        {
            parse_str($parse['query'], $params);
            unset($params[$p]);
            $url = $parse['path'] . '?' . http_build_query($params);
        }

        // if URL_MODE is not 0 / reference from U function
    		if (C('URL_MODEL'))
        {
            $depr = 2 === C('URL_PATHINFO_MODEL')? C('URL_PATHINFO_DEPR') : '/';
            $str  = $depr;

            foreach ($params as $var => $val)
            {
                $str .= $var . $depr . $val . $depr;
            }

            $str = substr($str, 0, -1);
            $url = str_replace($str, '', $host) . (strpos($host, ACTION_NAME) ? null : $depr . ACTION_NAME) . $str . C('URL_HTML_SUFFIX');

            // build url rule
            if (false !== strpos($url, "/$p/"))
            {
                $format = preg_replace('/\/p\/\d+/', "/$p/%d", $url);
            }
            else
            {
                $format = "$url/$p/%d" . C('URL_HTML_SUFFIX');
            }
        }
        else
        {
            $format = $url . (false === strpos($url, '?') ? '?' : '&') . "$p=%d";
    		}

    		// build first page link
    		$html['first'] = (1 < $this->p)
    		                ? $this->wrap_L . '<a href="' . sprintf($format, 1) . '">' . $this->config['first'] . '</a>' . $this->wrap_R
                        : null;

        // build prev page link
        $html['prev'] = (1 < $this->p)
                      ? $this->wrap_L . '<a href="' . sprintf($format, $this->p - 1) . '">' . $this->config['prev'] . '</a>' . $this->wrap_R
                      : null;

    		// build pages link
    		for ($i = $this->start; $i <= $this->end; ++$i)
        {
            $html['pages'] .= $this->wrap_L . ($i == $this->p ? "<span class=\"selected\">$i</span>" : '<a href="' . sprintf($format, $i) . "\">$i</a>") . $this->wrap_R;
    		}

    		// build next page link
        $html['next'] = $this->p < $this->pages
                      ? $this->wrap_L . '<a href="' . sprintf($format, $this->p + 1) . '">' . $this->config['next'] . '</a>' . $this->wrap_R
                      : null;


    		// build last page link
    		$html['last'] = (0 < $this->p && $this->pages > $this->p)
    		                ? $this->wrap_L . '<a href="' . sprintf($format, $this->pages) . '">' . $this->config['last'] . '</a>' . $this->wrap_R
                        : null;

    		// parse theme
    		$result = str_replace(
            array('%wrapL%', '%wrapR%', '%records%', '%page%', '%nowPage%', '%totalRow%', '%totalPage%', '%first%', '%prev%', '%linkPage%', '%next%', '%last%'),
            array($this->wrap_L, $this->wrap_R, $this->config['records'], $this->config['page'], $this->p, $this->rows, $this->pages, $html['first'], $html['prev'], $html['pages'], $html['next'], $html['last']),
            $this->config['theme']
        );

        return $result;

    }
}
?>
